package itsm.isperp.framework.data.mybatis.dao;

import itsm.isperp.framework.collection.map.LowercaseKeyHashMap;
import itsm.isperp.framework.data.commons.repository.BaseRepository;
import itsm.isperp.framework.data.domain.DataRequest;
import itsm.isperp.framework.data.domain.QueryFilter;
import itsm.isperp.framework.domain.IBean;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.ResultType;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

/**
 * 属性节点的映射器
 * 
 * @author lizx
 * @date 2013-2-15
 * @version V1.0
 */
public interface CUDMapper<T extends IBean> extends BaseRepository<T> {

	@InsertProvider(type = CUDTemplate.class, method = "save")
	@Override
	public <S extends T> int save(S entity);

	@InsertProvider(type = CUDTemplate.class, method = "save")
	@Override
	public int saveMap(@Param("tableName") String tableName,
			@Param("map") Map<String, Object> map);

	@InsertProvider(type = CUDTemplate.class, method = "dynamicSpecificSave")
	@Override
	public void dynamicSpecificSave(@Param("entity") T entity,
			@Param("includeColumns") Set<String> includeColumns);

	@UpdateProvider(type = CUDTemplate.class, method = "update")
	@Override
	public <S extends T> void update(S entity);

	@SelectProvider(type = CUDTemplate.class, method = "existsByClass")
	@Override
	public Object existsByClass(@Param("id") String id,
			@Param("clazz") Class<? extends IBean> clazz);

	@DeleteProvider(type = CUDTemplate.class, method = "deleteByClass")
	@Override
	public void deleteByClass(@Param("id") String id,
			@Param("clazz") Class<T> clazz);

	@DeleteProvider(type = CUDTemplate.class, method = "deleteAll")
	@Override
	public void deleteAll(@Param("clazz") Class<T> clazz);

	// @UpdateProvider(type = CUDTemplate.class, method = "dynamicUpdate")
	// @Override
	// public void dynamicUpdate(@Param("entity") T entity);

	// @UpdateProvider(type = CUDTemplate.class, method = "dynamicUpdateEntity")
	// @Override
	// public void dynamicUpdateEntity(@Param("entity") T entity,
	// @Param("oldEntity") T oldEntity);

	@UpdateProvider(type = CUDTemplate.class, method = "dynamicSpecificUpdate")
	@Override
	public void dynamicSpecificUpdate(@Param("entity") T entity,
			@Param("includeColumns") Set<String> includeColumns);

	@UpdateProvider(type = CUDTemplate.class, method = "dynamicButSpecificUpdate")
	@Override
	public void dynamicButSpecificUpdate(@Param("entity") T entity,
			@Param("includeColumns") Set<String> unIncludeColumns);

	// 由于在使用 SelectProvider 返回的结果需要指定ResultMap，考虑项目中的维护，此方法无法在动态脚本中使用
	@SelectProvider(type = CUDTemplate.class, method = "findOneByClass")
	@ResultType(LowercaseKeyHashMap.class)
	public LowercaseKeyHashMap<String, Object> findOneByClass(
			@Param("id") String id, @Param("clazz") Class<T> clazz);

	@SelectProvider(type = CUDTemplate.class, method = "findAllByClass")
	@ResultType(LowercaseKeyHashMap.class)
	public List<LowercaseKeyHashMap<String, Object>> findAllByClass(
			@Param("clazz") Class<T> clazz);

	@SelectProvider(type = CUDTemplate.class, method = "findOneByClassAndRequest")
	@ResultType(LowercaseKeyHashMap.class)
	public LowercaseKeyHashMap<String, Object> findOneByClassAndRequest(
			@Param("id") String id, @Param("clazz") Class<T> clazz,
			@Param("request") DataRequest request);

	@SelectProvider(type = CUDTemplate.class, method = "findOneByClassAndColumns")
	@ResultType(LowercaseKeyHashMap.class)
	public LowercaseKeyHashMap<String, Object> findOneByClassAndColumns(
			@Param("id") String id, @Param("clazz") Class<T> clazz,
			@Param("selectColumns") String[] selectColumns);

	@SelectProvider(type = CUDTemplate.class, method = "findAllCount")
	@ResultType(Long.class)
	@Override
	public Long findAllCount(@Param("clazz") Class<T> clazz,
			@Param("filter") QueryFilter filter);

}
